package com.example.service.impl;

import com.example.annotation.LogOperation;
import com.example.domain.dto.LoginRequest;
import com.example.domain.dto.LoginResponse;

import com.example.domain.response.HttpResponse;
import com.example.mapper.UserMapper;
import com.example.service.AuthService;
import com.example.utils.JwtTokenProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
/**
 * AuthServiceImpl类实现了AuthService接口，提供认证服务的具体实现。
 * 它使用了Spring Security的AuthenticationManager进行用户认证，
 * 并利用JwtTokenProvider生成JWT令牌，UserMapper用于用户数据的访问。
 */

@Service
@RequiredArgsConstructor

public class AuthServiceImpl implements AuthService {

    // 用于用户认证的AuthenticationManager
    private final AuthenticationManager authenticationManager;
    // 用于生成JWT令牌的JwtTokenProvider
    private final JwtTokenProvider tokenProvider;
    // 用于用户数据访问的UserMapper
    private final UserMapper userMapper;

    /**
     * 用户登录方法。
     * 该方法接收登录请求，使用AuthenticationManager进行用户认证，
     * 认证通过后生成JWT令牌并返回。
     *
     * @param request 登录请求，包含用户名和密码
     * @return 登录响应，包含JWT令牌
     */
    @LogOperation("用户登录")
    public HttpResponse<LoginResponse> login(LoginRequest request) {
        try {
            // 执行用户认证
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())
            );

            // 设置当前安全上下文的认证信息
            SecurityContextHolder.getContext().setAuthentication(authentication);

            // 生成JWT令牌
            String token = tokenProvider.generateToken(request.getUsername());
            System.out.println("登录成功");
            return HttpResponse.success(new LoginResponse(token));
        } catch (BadCredentialsException e) {
            e.printStackTrace();
            return (HttpResponse<LoginResponse>) HttpResponse.error(401, "用户名或密码错误");
        } catch (AuthenticationException e) {
            return (HttpResponse<LoginResponse>) HttpResponse.error(401, "认证失败");
        }
    }

    /**
     * 获取访问码列表。
     * 目前该方法直接返回一个空的访问码列表。
     *
     * @return 访问码列表
     */
    public HttpResponse<List<String>> getAccessCodes() {
        return HttpResponse.success(Collections.emptyList());
    }
}


